package net.zkbc.helloworld.shiro;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.web.filter.authc.FormAuthenticationFilter;
import org.apache.shiro.web.util.WebUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

import net.zkbc.shared.service.LoginAttemptsService;
import net.zkbc.shiro.authc.UsernamePasswordCaptchaToken;
import net.zkbc.shiro.web.filter.authc.JCaptchaValidateFilter;

@Component(ShiroAuthcFilter.INSTNAME)
@Lazy(false)
public class ShiroAuthcFilter extends FormAuthenticationFilter {

	public static final String INSTNAME = "authc";

	@Autowired
	private LoginAttemptsService loginAttemptsService;
	@Autowired
	private JCaptchaValidateFilter jcaptchaValidateFilter;

	@Override
	protected AuthenticationToken createToken(ServletRequest request, ServletResponse response) {
		String username = getUsername(request);
		if (loginAttemptsService.loginCaptchaRequired(username)) {
			return new UsernamePasswordCaptchaToken(username, getPassword(request), getCaptcha(request),
					isRememberMe(request), getHost(request));
		}

		return super.createToken(request, response);
	}

	@Override
	protected boolean onLoginSuccess(AuthenticationToken token, Subject subject, ServletRequest request,
			ServletResponse response) throws Exception {
		String username = (String) token.getPrincipal();

		loginAttemptsService.clearLoginAttempts(username);

		return super.onLoginSuccess(token, subject, request, response);
	}

	@Override
	protected boolean onLoginFailure(AuthenticationToken token, AuthenticationException e, ServletRequest request,
			ServletResponse response) {
		String username = (String) token.getPrincipal();

		loginAttemptsService.incrementLoginAttempts(username);

		return super.onLoginFailure(token, e, request, response);
	}

	protected String getCaptcha(ServletRequest request) {
		return WebUtils.getCleanParam(request, jcaptchaValidateFilter.getCaptchaParam());
	}

}
